home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / Miro_Downloader.exe / frontend_implementation / UIBackendDelegate.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-11-12  |  13.0 KB  |  359 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. import os
  5. import logging
  6. import subprocess
  7. import resources
  8. import webbrowser
  9. import _winreg
  10. import traceback
  11. import ctypes
  12. from gtcache import gettext as _
  13. from urlparse import urlparse
  14. import prefs
  15. import config
  16. import dialogs
  17. import feed
  18. import frontend
  19. import clipboard
  20. import urlcallbacks
  21. import util
  22. currentId = 1
  23.  
  24. def nextDialogId():
  25.     global currentId
  26.     rv = currentId
  27.     currentId += 1
  28.     return rv
  29.  
  30.  
  31. def getPrefillText(dialog):
  32.     if dialog.fillWithClipboardURL:
  33.         text = clipboard.getText()
  34.         if text is not None:
  35.             text = feed.normalizeFeedURL(text)
  36.             if text is not None and feed.validateFeedURL(text):
  37.                 return text
  38.             
  39.         
  40.     
  41.     if dialog.prefillCallback:
  42.         text = dialog.prefillCallback()
  43.         if text is not None:
  44.             return text
  45.         
  46.     
  47.     return ''
  48.  
  49.  
  50. def _makeSupportsArrayFromSecondElement(data):
  51.     components = components
  52.     import xpcom
  53.     arrayAbs = components.classes['@mozilla.org/supports-array;1'].createInstance()
  54.     array = arrayAbs.queryInterface(components.interfaces.nsISupportsArray)
  55.     for datum in data:
  56.         supportsStringAbs = components.classes['@mozilla.org/supports-string;1'].createInstance()
  57.         supportsString = supportsStringAbs.queryInterface(components.interfaces.nsISupportsString)
  58.         supportsString.data = datum[1]
  59.         array.AppendElement(supportsString)
  60.     
  61.     return array
  62.  
  63.  
  64. class UpdateAvailableDialog(dialogs.Dialog):
  65.     """Give the user a choice of 2 options (Yes/No, Ok/Cancel,
  66.     Migrate/Don't Migrate, etc.)
  67.     """
  68.     
  69.     def __init__(self, releaseNotes):
  70.         chromeURL = 'chrome://dtv/content/update_available_dialog.xul'
  71.         urlcallbacks.installCallback(chromeURL, self.urlCallback)
  72.         title = _('Update Available')
  73.         description = _('A new version of %s is available for download.') % config.get(prefs.LONG_APP_NAME)
  74.         self.releaseNotes = releaseNotes
  75.         super(UpdateAvailableDialog, self).__init__(title, description, [
  76.             dialogs.BUTTON_DOWNLOAD,
  77.             dialogs.BUTTON_NOT_NOW])
  78.  
  79.     
  80.     def urlCallback(self, url):
  81.         return True
  82.  
  83.  
  84.  
  85. class UIBackendDelegate:
  86.     openDialogs = { }
  87.     currentMenuItems = None
  88.     
  89.     def performStartupTasks(self, terminationCallback):
  90.         terminationCallback(None)
  91.  
  92.     
  93.     def showContextMenu(self, menuItems):
  94.         UIBackendDelegate.currentMenuItems = menuItems
  95.         
  96.         def getLabelString(menuItem):
  97.             if menuItem.callback is not None or menuItem.label == '':
  98.                 return menuItem.label
  99.             else:
  100.                 return '_' + menuItem.label
  101.  
  102.         menuString = []([ getLabelString(m) for m in menuItems ])
  103.         frontend.jsBridge.showContextMenu(menuString)
  104.  
  105.     
  106.     def maximizeWindow(self):
  107.         frontend.jsBridge.maximizeWindow()
  108.  
  109.     
  110.     def runDialog(self, dialog):
  111.         id = nextDialogId()
  112.         self.openDialogs[id] = dialog
  113.         if isinstance(dialog, dialogs.ChoiceDialog):
  114.             frontend.jsBridge.showChoiceDialog(id, dialog.title, dialog.description, dialog.buttons[0].text, dialog.buttons[1].text)
  115.         elif isinstance(dialog, dialogs.CheckboxTextboxDialog):
  116.             frontend.jsBridge.showCheckboxTextboxDialog(id, dialog.title, dialog.description, dialog.buttons[0].text, dialog.buttons[1].text, dialog.checkbox_text, dialog.checkbox_value, dialog.textbox_value)
  117.         elif isinstance(dialog, dialogs.CheckboxDialog):
  118.             frontend.jsBridge.showCheckboxDialog(id, dialog.title, dialog.description, dialog.buttons[0].text, dialog.buttons[1].text, dialog.checkbox_text, dialog.checkbox_value)
  119.         elif isinstance(dialog, dialogs.ThreeChoiceDialog):
  120.             frontend.jsBridge.showThreeChoiceDialog(id, dialog.title, dialog.description, dialog.buttons[0].text, dialog.buttons[1].text, dialog.buttons[2].text)
  121.         elif isinstance(dialog, dialogs.MessageBoxDialog):
  122.             frontend.jsBridge.showMessageBoxDialog(id, dialog.title, dialog.description)
  123.         elif isinstance(dialog, dialogs.HTTPAuthDialog):
  124.             frontend.jsBridge.showHTTPAuthDialog(id, dialog.description)
  125.         elif isinstance(dialog, dialogs.TextEntryDialog):
  126.             frontend.jsBridge.showTextEntryDialog(id, dialog.title, dialog.description, dialog.buttons[0].text, dialog.buttons[1].text, getPrefillText(dialog))
  127.         elif isinstance(dialog, UpdateAvailableDialog):
  128.             frontend.jsBridge.showUpdateAvailableDialog(id, dialog.title, dialog.description, dialog.buttons[0].text, dialog.buttons[1].text, dialog.releaseNotes)
  129.         elif isinstance(dialog, dialogs.SearchChannelDialog):
  130.             engines = _makeSupportsArrayFromSecondElement(dialog.engines)
  131.             channels = _makeSupportsArrayFromSecondElement(dialog.channels)
  132.             defaultTerm = ''
  133.             if len(dialog.channels) > 0:
  134.                 defaultChannelId = dialog.channels[0][0]
  135.             else:
  136.                 defaultChannelId = 0
  137.             defaultEngineName = dialog.defaultEngine
  138.             defaultURL = ''
  139.             if dialog.term:
  140.                 defaultTerm = dialog.term
  141.             
  142.             if dialog.style == dialog.CHANNEL:
  143.                 if dialog.location is not None:
  144.                     defaultChannelId = dialog.location
  145.                 
  146.             elif dialog.style == dialog.ENGINE:
  147.                 if dialog.location is not None:
  148.                     defaultEngineName = dialog.location
  149.                 
  150.             elif dialog.style == dialog.URL:
  151.                 if dialog.location is not None:
  152.                     defaultURL = dialog.location
  153.                 
  154.             
  155.             defaultChannel = 0
  156.             defaultEngine = 0
  157.             for i in xrange(len(dialog.channels)):
  158.                 if dialog.channels[i][0] == defaultChannelId:
  159.                     defaultChannel = i
  160.                     break
  161.                     continue
  162.             
  163.             for i in xrange(len(dialog.engines)):
  164.                 if dialog.engines[i][0] == defaultEngineName:
  165.                     defaultEngine = i
  166.                     break
  167.                     continue
  168.             
  169.             frontend.jsBridge.showSearchChannelDialog(id, channels, engines, defaultTerm, dialog.style, defaultChannel, defaultEngine, defaultURL)
  170.         else:
  171.             del self.openDialogs[id]
  172.             dialog.runCallback(None)
  173.  
  174.     
  175.     def askForOpenPathname(self, title, callback, defaultDirectory = None, typeString = None, types = None):
  176.         id = nextDialogId()
  177.         self.openDialogs[id] = callback
  178.         frontend.jsBridge.showOpenDialog(id, title, defaultDirectory, typeString, types)
  179.  
  180.     
  181.     def askForSavePathname(self, title, callback, defaultDirectory = None, defaultFilename = None):
  182.         id = nextDialogId()
  183.         self.openDialogs[id] = callback
  184.         frontend.jsBridge.showSaveDialog(id, title, defaultDirectory, defaultFilename)
  185.  
  186.     
  187.     def handleFileDialog(self, dialogID, pathname):
  188.         
  189.         try:
  190.             callback = self.openDialogs.pop(dialogID)
  191.         except KeyError:
  192.             return None
  193.  
  194.         util.trapCall('File dialog callback', callback, pathname)
  195.  
  196.     
  197.     def handleContextMenu(self, index):
  198.         self.currentMenuItems[index].activate()
  199.  
  200.     
  201.     def handleDialog(self, dialogID, buttonIndex, *args, **kwargs):
  202.         
  203.         try:
  204.             dialog = self.openDialogs.pop(dialogID)
  205.         except KeyError:
  206.             return None
  207.  
  208.         if buttonIndex is not None:
  209.             choice = dialog.buttons[buttonIndex]
  210.         else:
  211.             choice = None
  212.         if isinstance(dialog, dialogs.SearchChannelDialog):
  213.             dialog.term = kwargs['term']
  214.             dialog.style = kwargs['style']
  215.             if choice == dialogs.BUTTON_CREATE_CHANNEL:
  216.                 
  217.                 try:
  218.                     if dialog.style == dialog.CHANNEL:
  219.                         dialog.location = dialog.channels[int(kwargs['loc'])][0]
  220.                     elif dialog.style == dialog.ENGINE:
  221.                         dialog.location = dialog.engines[int(kwargs['loc'])][0]
  222.                     elif dialog.style == dialog.URL:
  223.                         dialog.location = kwargs['loc']
  224.                 choice = dialogs.BUTTON_CANCEL
  225.  
  226.             
  227.             kwargs = { }
  228.         
  229.         dialog.runCallback(choice, *args, **kwargs)
  230.  
  231.     
  232.     def openExternalURL(self, url):
  233.         if len(url) > 2047:
  234.             url = url[:2047]
  235.         
  236.         
  237.         try:
  238.             webbrowser.get('windows-default').open_new(url)
  239.         except:
  240.             print 'WARNING: Error opening URL: %r' % url
  241.             traceback.print_exc()
  242.             recommendURL = config.get(prefs.RECOMMEND_URL)
  243.             if url.startswith(config.get(prefs.VIDEOBOMB_URL)):
  244.                 title = _('Error Bombing Item')
  245.             elif url.startswith(recommendURL):
  246.                 title = _('Error Recommending Item')
  247.             else:
  248.                 title = _('Error Opening Website')
  249.             (scheme, host, path, params, query, fragment) = urlparse(url)
  250.             shortURL = '%s:%s%s' % (scheme, host, path)
  251.             msg = _('There was an error opening %s.  Please try again in a few seconds') % shortURL
  252.             dialogs.MessageBoxDialog(title, msg).run()
  253.  
  254.  
  255.     
  256.     def revealFile(self, filename):
  257.         os.startfile(os.path.dirname(filename))
  258.  
  259.     
  260.     def notifyDownloadCompleted(self, item):
  261.         pass
  262.  
  263.     
  264.     def notifyDownloadFailed(self, item):
  265.         pass
  266.  
  267.     
  268.     def updateAvailableItemsCountFeedback(self, count):
  269.         pass
  270.  
  271.     
  272.     def notifyUnkownErrorOccurence(self, when, log = ''):
  273.         if config.get(prefs.SHOW_ERROR_DIALOG):
  274.             frontend.jsBridge.showBugReportDialog(when, log)
  275.         
  276.  
  277.     
  278.     def copyTextToClipboard(self, text):
  279.         frontend.jsBridge.copyTextToClipboard(text)
  280.  
  281.     
  282.     def setRunAtStartup(self, value):
  283.         runSubkey = 'Software\\Microsoft\\Windows\\CurrentVersion\\Run'
  284.         
  285.         try:
  286.             folder = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, runSubkey, 0, _winreg.KEY_SET_VALUE)
  287.         except WindowsError:
  288.             e = None
  289.             if e.errno == 2:
  290.                 folder = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, runSubkey)
  291.             else:
  292.                 raise 
  293.         except:
  294.             e.errno == 2
  295.  
  296.         if value:
  297.             filename = os.path.join(resources.resourceRoot(), '..', 'Miro.exe')
  298.             filename = os.path.normpath(filename)
  299.             themeName = config.get(prefs.THEME_NAME)
  300.             if themeName is not None:
  301.                 filename = '%s --theme "%s"' % (filename, themeName.replace('\\', '\\\\').replace('"', '\\"'))
  302.             
  303.             _winreg.SetValueEx(folder, config.get(prefs.LONG_APP_NAME), 0, _winreg.REG_SZ, filename)
  304.         else:
  305.             
  306.             try:
  307.                 _winreg.DeleteValue(folder, config.get(prefs.LONG_APP_NAME))
  308.             except WindowsError:
  309.                 e = None
  310.                 if e.errno == 2:
  311.                     pass
  312.                 else:
  313.                     raise 
  314.             except:
  315.                 e.errno == 2
  316.  
  317.  
  318.     
  319.     def killProcess(self, pid):
  320.         if pid is not None:
  321.             PROCESS_TERMINATE = 1
  322.             handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, pid)
  323.             ctypes.windll.kernel32.TerminateProcess(handle, -1)
  324.             ctypes.windll.kernel32.CloseHandle(handle)
  325.         
  326.  
  327.     
  328.     def launchDownloadDaemon(self, oldpid, env):
  329.         self.killProcess(oldpid)
  330.         for key, value in env.items():
  331.             os.environ[key] = value
  332.         
  333.         os.environ['DEMOCRACY_DOWNLOADER_LOG'] = config.get(prefs.DOWNLOADER_LOG_PATHNAME)
  334.         downloaderPath = os.path.join(resources.resourceRoot(), '..', 'Miro_Downloader.exe')
  335.         startupinfo = subprocess.STARTUPINFO()
  336.         startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
  337.         subprocess.Popen(downloaderPath, stdout = subprocess.PIPE, stderr = subprocess.PIPE, stdin = subprocess.PIPE, startupinfo = startupinfo)
  338.  
  339.     
  340.     def handleNewUpdate(self, update_item):
  341.         url = update_item['enclosures'][0]['href']
  342.         
  343.         try:
  344.             releaseNotes = update_item['description']
  345.         except:
  346.             logging.warn("Couldn't fetch release notes")
  347.             releaseNotes = ''
  348.  
  349.         dialog = UpdateAvailableDialog(releaseNotes)
  350.         
  351.         def callback(dialog):
  352.             if dialog.choice == dialogs.BUTTON_DOWNLOAD:
  353.                 self.openExternalURL(url)
  354.             
  355.  
  356.         dialog.run(callback)
  357.  
  358.  
  359.